import json
import pandas as pd
from feature_conf.config.constant import GenericConfigConstant
from datetime import datetime, timedelta
from utils.common import fea_div_v2
from feature_set.sms.utils.data_process import time_trans
mon_list = GenericConfigConstant.MONTH_LIST
COUNTRY_TIME_ZONE = GenericConfigConstant.COUNTRY_TIME_ZONE


def format_sc_card_size(sdcard_available_size):
    sd_card_available_size = sdcard_available_size.lower().strip()
    if sd_card_available_size != '':
        if sd_card_available_size[-1:] == 'g':
            sd_card_available_size = float(sd_card_available_size[:-1])
        elif sd_card_available_size[-2:] == 'gb':
            sd_card_available_size = float(sd_card_available_size[:-2])
        elif sd_card_available_size[-1:] == 'm':
            sd_card_available_size = float(sd_card_available_size[:-1]) / 1024
        elif sd_card_available_size[-2:] == 'mb':
            sd_card_available_size = float(sd_card_available_size[:-2]) / 1024
        elif sd_card_available_size[-4:] == 'byte':
            sd_card_available_size = float(sd_card_available_size[:-4]) / 1024 / 1024 / 1024
        elif sd_card_available_size.isdigit():
            sd_card_available_size = float(sd_card_available_size) / 1024 / 1024 / 1024
        elif type(eval(sd_card_available_size)) == float:
            sd_card_available_size = eval(sd_card_available_size)
        else:
            sd_card_available_size = sd_card_available_size
    else:
        sd_card_available_size = -999
    return sd_card_available_size


def format_boot_date(boot_date, country_id):
    boot_date = boot_date.lower().strip('').replace(',', '').replace('.', '')
    tz = COUNTRY_TIME_ZONE[country_id]
    if 'am' in boot_date or 'pm' in boot_date:
        date_str_cleaned = boot_date.replace('at ', '').strip()
        flag_list = date_str_cleaned.split(' ')

        if flag_list[0] in mon_list:
            flag_list[0], flag_list[1] = flag_list[1], flag_list[0]
        date_str_cleaned = ' '.join(flag_list)
        if 'pm' in date_str_cleaned:
            date_obj = datetime.strptime(date_str_cleaned.replace(' pm', '').replace('pm', '').strip(),
                                         '%d %b %Y %I:%M:%S')
            if date_obj.hour != 12:
                date_obj = date_obj.replace(hour=date_obj.hour + 12)
        else:
            date_obj = datetime.strptime(date_str_cleaned.replace(' am', '').replace('am', '').strip(),
                                         '%d %b %Y %I:%M:%S')
        formatted_date = date_obj.strftime('%Y-%m-%d %H:%M:%S')
        return formatted_date

    elif 'at' in boot_date:
        date_str_cleaned = boot_date.replace('at ', '').strip()
        flag_list = date_str_cleaned.split(' ')
        if flag_list[0] in mon_list:
            flag_list[0], flag_list[1] = flag_list[1], flag_list[0]
        date_str_cleaned = ' '.join(flag_list)
        try:
            date_obj = datetime.strptime(date_str_cleaned, '%d %b %Y %I:%M:%S')
        except:
            date_obj = datetime.strptime(date_str_cleaned, '%d %b %Y %H:%M:%S')
        formatted_date = date_obj.strftime('%Y-%m-%d %H:%M:%S')
        return formatted_date

    elif len(boot_date) == 19 and ' ' in boot_date and '-' in boot_date:
        formatted_date = boot_date.strip()
        return formatted_date
    elif len(list(set(boot_date.split(' ')) & set(mon_list))) > 0:
        try:
            date_obj = datetime.strptime(boot_date, '%d %b %Y %I:%M:%S')
            formatted_date = date_obj.strftime('%Y-%m-%d %H:%M:%S')
            return formatted_date
        except:
            date_obj = datetime.strptime(boot_date, '%d %b %Y %H:%M:%S')
            formatted_date = date_obj.strftime('%Y-%m-%d %H:%M:%S')
            return formatted_date
    elif len(boot_date) == 10:
        if '-' in boot_date:
            date_obj = datetime.strptime(boot_date, '%Y-%m-%d')
            formatted_date = date_obj.strftime('%Y-%m-%d %H:%M:%S')
            return formatted_date
        else:
            date_obj = datetime.utcfromtimestamp(int(boot_date)) + timedelta(hours=tz)
            formatted_date = date_obj.strftime('%Y-%m-%d %H:%M:%S')
            return formatted_date
    else:
        return '2099-12-31 23:59:59'


def format_device_data(device, country_id='mx', current_apply_time=None):
    # 过滤掉帐数据
    device = device[device.device_info.map(lambda x : (x is not None and len(x.strip())>0) and (len(json.loads(x))>=2) ) ].reset_index(drop=True)

    merge_df = pd.concat([device.loc[:, ['user_id', 'update_time']],
                          pd.json_normalize(device.device_info.apply(lambda x: json.loads(x)))], axis=1)
    merge_df['update_time'] = merge_df['update_time'].apply(lambda x: time_trans(x, country_id))
    col_need = ['user_id',
                'update_time',
                'advertising_id',
                'and_id',
                'background_recovery_times',
                'battery_health',
                'battery_power',
                'battery_temperature',
                'boot_date',
                'boot_time',
                'charge_type',
                'client_type',
                'deviceId',
                'deviceBrand',
                'gaid',
                'has_gravity_sensor',
                'has_gyroscope_sensor',
                'ip',
                'is_airplane_mode',
                'is_charging',
                'is_mock_location',
                'is_root',
                'is_tablet',
                'is_usb_debug',
                'is_using_proxy_port',
                'is_using_vpn',
                'keyboard',
                'loan_page_stay_time',
                'locale_iso_3_country',
                'ram_total_size',
                'ram_usable_size',
                'read_privacy_agreement_time',
                'read_privacy_agreement_times',
                'ringer_mode',
                'screen_brightness',
                'sd_card_available_size',
                'sim_count']
    merge_list = list(merge_df.columns)
    comm_cols = [col for col in col_need if col in merge_list]
    other_cols = [col for col in col_need if col not in merge_list]
    if len(other_cols) == 0:
        merge_df = merge_df[col_need]
    else:
        merge_df = merge_df[comm_cols]
        for sub_col in other_cols:
            merge_df[sub_col] = None

    merge_df = merge_df[col_need]
    merge_df['update_time'] = merge_df.update_time.astype(str)
    merge_df['background_recovery_times'] = pd.to_numeric(merge_df.background_recovery_times)

    merge_df['battery_power'] = pd.to_numeric(merge_df.battery_power)

    merge_df['battery_temperature'] = pd.to_numeric(merge_df.battery_temperature)

    merge_df['boot_time'] = pd.to_numeric(merge_df.boot_time)

    merge_df['loan_page_stay_time'] = pd.to_numeric(merge_df.loan_page_stay_time)

    merge_df['ram_total_size'] = pd.to_numeric(merge_df.ram_total_size)

    merge_df['ram_usable_size'] = pd.to_numeric(merge_df.ram_usable_size)

    merge_df['read_privacy_agreement_time'] = pd.to_numeric(merge_df.read_privacy_agreement_time)

    merge_df['read_privacy_agreement_times'] = pd.to_numeric(merge_df.read_privacy_agreement_times)

    merge_df['screen_brightness'] = pd.to_numeric(merge_df.screen_brightness)

    merge_df['sdcard_available_size'] = merge_df.sd_card_available_size.apply(lambda x: format_sc_card_size(x))

    merge_df['boot_date'] = merge_df.boot_date.apply(lambda x: format_boot_date(x, country_id))
    merge_df['is_root'] = merge_df.is_root.apply(lambda x: 1 if x else 0)
    merge_df['day_inter'] = (pd.to_datetime(current_apply_time) - pd.to_datetime(merge_df['update_time'])).dt.days
    merge_df['boot_day_inter'] = (pd.to_datetime(current_apply_time) - pd.to_datetime(merge_df['boot_date'])).dt.days
    return merge_df


def get_device_list_features(merge_df):
    day_list = [1, 3, 7, 15, 30, 60, 90, 180]
    feature_value_list = []
    feature_name_list = []
    for day in day_list:
        tmp_df = merge_df[merge_df.day_inter <= day].copy()
        report_cnt = tmp_df.shape[0]  # 最近N天上报设备数据次数
        advertising_id_cnt = tmp_df.advertising_id.nunique()  # 最近N天上报的advertising_id的个数
        and_id_cnt = tmp_df.and_id.nunique()  # 最近N天上报的and_id的个数
        boot_date_cnt = tmp_df.boot_date.nunique()  # 最近N天设备重启次数
        device_id_cnt = tmp_df.deviceId.nunique()  # 最近N天设备id上报个数
        device_brand_cnt = tmp_df.deviceBrand.nunique()  # 最近N天设备品牌上报个数
        gaid_cnt = tmp_df.gaid.nunique()  # 最近N天设备gaid上报个数
        ip_cnt = tmp_df.ip.nunique()  # 最近N天设备ip上报个数
        iso_country_cnt = tmp_df.locale_iso_3_country.nunique()  # 最近N天iso_country上报个数
        background_recovery_times_sum = tmp_df.background_recovery_times.sum()  # 最近N天从后台恢复次数的和
        background_recovery_times_max = tmp_df.background_recovery_times.max()  # 最近N天从后台恢复次数的最大值
        background_recovery_times_min = tmp_df.background_recovery_times.min()  # 最近N天从后台恢复次数的最小值
        background_recovery_times_mean = tmp_df.background_recovery_times.mean()  # 最近N天从后台恢复次数的平均值
        battery_health_1_cnt = len(tmp_df[tmp_df.battery_health == 1])  # 最近N天电池电量状态未知的次数
        battery_health_2_cnt = len(tmp_df[tmp_df.battery_health == 2])  # 最近N天电池电量状态良好的次数
        battery_health_3_cnt = len(tmp_df[tmp_df.battery_health == 3])  # 最近N天电池电量状态过热的次数

        battery_health_1_rate = fea_div_v2(battery_health_1_cnt, report_cnt)  # 最近N天电池电量状态未知的比例
        battery_health_2_rate = fea_div_v2(battery_health_2_cnt, report_cnt)  # 最近N天电池电量状态良好的比例
        battery_health_3_rate = fea_div_v2(battery_health_3_cnt, report_cnt)  # 最近N天电池电量状态过热的比例

        battery_power_std = tmp_df.battery_power.std()  # 最近N天电池电量的标准差
        battery_power_max = tmp_df.battery_power.max()  # 最近N天电池电量的最大值
        battery_power_min = tmp_df.battery_power.min()  # 最近N天电池电量的最小值
        battery_power_mean = tmp_df.battery_power.mean()  # 最近N天电池电量的平均值

        battery_temperature_std = tmp_df.battery_temperature.std()  # 最近N天电池温度的标准差
        battery_temperature_max = tmp_df.battery_temperature.max()  # 最近N天电池温度的最大值
        battery_temperature_min = tmp_df.battery_temperature.min()  # 最近N天电池温度的最小值
        battery_temperature_mean = tmp_df.battery_temperature.mean()  # 最近N天电池温度的平均值

        boot_time_std = tmp_df.boot_time.std()  # 最近N天开机时长的标准差
        boot_time_max = tmp_df.boot_time.max()  # 最近N天开机时长的最大值
        boot_time_min = tmp_df.boot_time.min()  # 最近N天开机时长的最小值
        boot_time_mean = tmp_df.boot_time.mean()  # 最近N天开机时长的平均值

        charge_type_1_cnt = len(tmp_df[tmp_df.charge_type == 1])  # 最近N天充电类型为1的次数
        charge_type_2_cnt = len(tmp_df[tmp_df.charge_type == 2])  # 最近N天充电类型为2的次数
        charge_type_4_cnt = len(tmp_df[tmp_df.charge_type == 4])  # 最近N天充电类型为4的次数

        charge_type_1_rate = fea_div_v2(charge_type_1_cnt, report_cnt)  # 最近N天充电类型为1的比例
        charge_type_2_rate = fea_div_v2(charge_type_2_cnt, report_cnt)  # 最近N天充电类型为2的比例
        charge_type_4_rate = fea_div_v2(charge_type_4_cnt, report_cnt)  # 最近N天充电类型为4的比例

        client_type_0_cnt = len(tmp_df[tmp_df.client_type == 0])  # 最近N天客户端类型为0的次数
        client_type_1_cnt = len(tmp_df[tmp_df.client_type == 1])  # 最近N天客户端类型为1的次数

        client_type_0_rate = fea_div_v2(client_type_0_cnt, report_cnt)  # 最近N天客户端类型为0的比例
        client_type_1_rate = fea_div_v2(client_type_1_cnt, report_cnt)  # 最近N天客户端类型为1的比例

        has_gravity_sensor_0_cnt = len(tmp_df[tmp_df.has_gravity_sensor == 0])  # 最近N天重力传感器类型为0的次数
        has_gravity_sensor_1_cnt = len(tmp_df[tmp_df.has_gravity_sensor == 1])  # 最近N天重力传感器类型为1的次数

        has_gravity_sensor_0_rate = fea_div_v2(has_gravity_sensor_0_cnt, report_cnt)  # 最近N天重力传感器类型为0的比例
        has_gravity_sensor_1_rate = fea_div_v2(has_gravity_sensor_1_cnt, report_cnt)  # 最近N天重力传感器类型为0的比例

        has_gyroscope_sensor_0_cnt = len(tmp_df[tmp_df.has_gyroscope_sensor == 0])  # 最近N天陀螺仪传感器类型为0的次数
        has_gyroscope_sensor_1_cnt = len(tmp_df[tmp_df.has_gyroscope_sensor == 1])  # 最近N天陀螺仪传感器类型为1的次数

        has_gyroscope_sensor_0_rate = fea_div_v2(has_gyroscope_sensor_0_cnt, report_cnt)  # 最近N天陀螺仪传感器类型为0的比例
        has_gyroscope_sensor_1_rate = fea_div_v2(has_gyroscope_sensor_1_cnt, report_cnt)  # 最近N天陀螺仪传感器类型为1的比例

        is_airplane_mode_0_cnt = len(tmp_df[tmp_df.is_airplane_mode == 0])  # 最近N天飞行模式类型为0的次数
        is_airplane_mode_1_cnt = len(tmp_df[tmp_df.is_airplane_mode == 1])  # 最近N天飞行模式类型为1的次数

        is_airplane_moder_0_rate = fea_div_v2(is_airplane_mode_0_cnt, report_cnt)  # 最近N天飞行模式类型为0的比例
        is_airplane_mode_1_rate = fea_div_v2(is_airplane_mode_1_cnt, report_cnt)  # 最近N天飞行模式类型为1的比例

        is_airplane_mode_0_cnt = len(tmp_df[tmp_df.is_airplane_mode == 0])  # 最近N天飞行模式类型为0的次数
        is_airplane_mode_1_cnt = len(tmp_df[tmp_df.is_airplane_mode == 1])  # 最近N天飞行模式类型为1的次数

        is_airplane_mode_0_rate = fea_div_v2(is_airplane_mode_0_cnt, report_cnt)  # 最近N天飞行模式类型为0的占比
        is_airplane_mode_1_rate = fea_div_v2(is_airplane_mode_1_cnt, report_cnt)  # 最近N天飞行模式类型为1的占比

        is_charging_1_cnt = len(tmp_df[tmp_df.is_charging == 1])  # 最近N天正在充电类型为1的次数
        is_charging_2_cnt = len(tmp_df[tmp_df.is_charging == 2])  # 最近N天正在充电类型为2的次数
        is_charging_3_cnt = len(tmp_df[tmp_df.is_charging == 3])  # 最近N天正在充电类型为3的次数
        is_charging_4_cnt = len(tmp_df[tmp_df.is_charging == 4])  # 最近N天正在充电类型为4的次数
        is_charging_5_cnt = len(tmp_df[tmp_df.is_charging == 5])  # 最近N天正在充电类型为5的次数

        is_charging_1_rate = fea_div_v2(is_charging_1_cnt, report_cnt)  # 最近N天正在充电类型为1的占比
        is_charging_2_rate = fea_div_v2(is_charging_2_cnt, report_cnt)  # 最近N天正在充电类型为2的占比
        is_charging_3_rate = fea_div_v2(is_charging_3_cnt, report_cnt)  # 最近N天正在充电类型为3的占比
        is_charging_4_rate = fea_div_v2(is_charging_4_cnt, report_cnt)  # 最近N天正在充电类型为4的占比
        is_charging_5_rate = fea_div_v2(is_charging_5_cnt, report_cnt)  # 最近N天正在充电类型为5的占比

        is_mock_location_0_cnt = len(tmp_df[tmp_df.is_mock_location == 0])  # 最近N天位置模拟类型为0的次数
        is_mock_location_1_cnt = len(tmp_df[tmp_df.is_mock_location == 1])  # 最近N天位置模拟类型为1的次数

        is_mock_location_0_rate = fea_div_v2(is_mock_location_0_cnt, report_cnt)  # 最近N天位置模拟类型为0的占比
        is_mock_location_1_rate = fea_div_v2(is_mock_location_1_cnt, report_cnt)  # 最近N天位置模拟类型为1的占比

        is_root_0_cnt = len(tmp_df[tmp_df.is_root == 0])  # 最近N天root类型为0的次数
        is_root_1_cnt = len(tmp_df[tmp_df.is_root == 1])  # 最近N天root类型为1的次数

        is_root_0_rate = fea_div_v2(is_root_0_cnt, report_cnt)  # 最近N天root类型为0的占比
        is_root_1_rate = fea_div_v2(is_root_1_cnt, report_cnt)  # 最近N天root类型为1的占比

        is_tablet_0_cnt = len(tmp_df[tmp_df.is_tablet == 0])  # 最近N天为上报为非平板类型的次数
        is_tablet_1_cnt = len(tmp_df[tmp_df.is_tablet == 1])  # 最近N天为上报为平板类型的次数

        is_tablet_0_rate = fea_div_v2(is_tablet_0_cnt, report_cnt)  # 最近N天为上报为非平板类型的占比
        is_tablet_1_rate = fea_div_v2(is_tablet_1_cnt, report_cnt)  # 最近N天为上报为平板类型的占比

        is_usb_debug_0_cnt = len(tmp_df[tmp_df.is_usb_debug == 0])  # 最近N天为上报debug调试关闭的次数
        is_usb_debug_1_cnt = len(tmp_df[tmp_df.is_usb_debug == 1])  # 最近N天为上报debug调试开启的次数

        is_usb_debug_0_rate = fea_div_v2(is_usb_debug_0_cnt, report_cnt)  # 最近N天为上报debug调试关闭的占比
        is_usb_debug_1_rate = fea_div_v2(is_usb_debug_1_cnt, report_cnt)  # 最近N天为上报debug调试开启的占比

        is_usb_vpn_0_cnt = len(tmp_df[tmp_df.is_using_vpn == 0])  # 最近N天为上报未使用VPN的次数
        is_usb_vpn_1_cnt = len(tmp_df[tmp_df.is_using_vpn == 1])  # 最近N天为上报使用VPN的次数

        is_usb_vpn_0_rate = fea_div_v2(is_usb_vpn_0_cnt, report_cnt)  # 最近N天为上报未使用VPN的占比
        is_usb_vpn_1_rate = fea_div_v2(is_usb_vpn_1_cnt, report_cnt)  # 最近N天为上报使用VPN的次占比

        is_keyboard_0_cnt = len(tmp_df[tmp_df.keyboard == 0])  # 最近N天上报有物理按键次数
        is_keyboard_1_cnt = len(tmp_df[tmp_df.keyboard == 1])  # 最近N天上报有物理按键次数

        is_keyboard_0_rate = fea_div_v2(is_keyboard_0_cnt, report_cnt)  # 最近N天上报有物理按键占比
        is_keyboard_1_rate = fea_div_v2(is_keyboard_1_cnt, report_cnt)  # 最近N天上报有物理按键占比

        ringer_mode_0_cnt = len(tmp_df[tmp_df.ringer_mode == 0])  # 最近N天上报铃声模式为0的次数
        ringer_mode_1_cnt = len(tmp_df[tmp_df.ringer_mode == 1])  # 最近N天上报铃声模式为1的次数
        ringer_mode_2_cnt = len(tmp_df[tmp_df.ringer_mode == 2])  # 最近N天上报铃声模式为2的次数

        ringer_mode_0_rate = fea_div_v2(ringer_mode_0_cnt, report_cnt)  # 最近N天上报铃声模式为0的占比
        ringer_mode_1_rate = fea_div_v2(ringer_mode_1_cnt, report_cnt)  # 最近N天上报铃声模式为1的占比
        ringer_mode_1_rate = fea_div_v2(ringer_mode_2_cnt, report_cnt)  # 最近N天上报铃声模式为2的占比

        sim_count_0_cnt = len(tmp_df[tmp_df.ringer_mode == 0])  # 最近N天上报sim卡数量为0的次数
        sim_count_1_cnt = len(tmp_df[tmp_df.ringer_mode == 1])  # 最近N天上报sim卡数量为1的次数
        sim_count_2_cnt = len(tmp_df[tmp_df.ringer_mode == 2])  # 最近N天上报sim卡数量为2的次数
        sim_count_4_cnt = len(tmp_df[tmp_df.ringer_mode == -1])  # 最近N天上报sim卡数量为-1的次数

        sim_count_0_rate = fea_div_v2(sim_count_0_cnt, report_cnt)  # 最近N天上报sim卡数量为0的占比
        sim_count_1_rate = fea_div_v2(sim_count_1_cnt, report_cnt)  # 最近N天上报sim卡数量为1的占比
        sim_count_1_rate = fea_div_v2(sim_count_2_cnt, report_cnt)  # 最近N天上报sim卡数量为2的占比
        sim_count_1_rate = fea_div_v2(sim_count_4_cnt, report_cnt)  # 最近N天上报sim卡数量为-1的占比

        loan_page_stay_time_std = tmp_df.loan_page_stay_time.std()  # 最近N天贷款页面停留时长的标准差
        loan_page_stay_time_max = tmp_df.loan_page_stay_time.max()  # 最近N天贷款页面停留时长的最大值
        loan_page_stay_time_min = tmp_df.loan_page_stay_time.min()  # 最近N天贷款页面停留时长的最小值
        loan_page_stay_time_mean = tmp_df.loan_page_stay_time.mean()  # 最近N天贷款页面停留时长的平均值

        ram_total_size_std = tmp_df.ram_total_size.std()  # 最近N天运行内存总大小的标准差
        ram_total_size_max = tmp_df.ram_total_size.max()  # 最近N天运行内存总大小的最大值
        ram_total_size_min = tmp_df.ram_total_size.min()  # 最近N天运行内存总大小的最小值
        ram_total_size_mean = tmp_df.ram_total_size.mean()  # 最近N天运行内存总大小的平均值

        ram_usable_size_std = tmp_df.ram_usable_size.std()  # 最近N天运行内存可用大小的标准差
        ram_usable_size_max = tmp_df.ram_usable_size.max()  # 最近N天运行内存可用大小的最大值
        ram_usable_size_min = tmp_df.ram_usable_size.min()  # 最近N天运行内存可用大小的最小值
        ram_usable_size_mean = tmp_df.ram_usable_size.mean()  # 最近N天运行内存可用大小的平均值

        read_privacy_agreement_time_std = tmp_df.read_privacy_agreement_time.std()  # 最近N天运隐私协议时长的标准差
        read_privacy_agreement_time_max = tmp_df.read_privacy_agreement_time.max()  # 最近N天运隐私协议时长的最大值
        read_privacy_agreement_time_min = tmp_df.read_privacy_agreement_time.min()  # 最近N天运隐私协议时长的最小值
        read_privacy_agreement_time_mean = tmp_df.read_privacy_agreement_time.mean()  # 最近N天运隐私协议时长的平均值

        read_privacy_agreement_times_std = tmp_df.read_privacy_agreement_times.std()  # 最近N天隐私协议次数的标准差
        read_privacy_agreement_times_max = tmp_df.read_privacy_agreement_times.max()  # 最近N天隐私协议次数的最大值
        read_privacy_agreement_times_min = tmp_df.read_privacy_agreement_times.min()  # 最近N天隐私协议次数的最小值
        read_privacy_agreement_times_mean = tmp_df.read_privacy_agreement_times.mean()  # 最近N天隐私协议次数的平均值

        screen_brightness_std = tmp_df.screen_brightness.std()  # 最近N天屏幕亮度的标准差
        screen_brightness_max = tmp_df.screen_brightness.max()  # 最近N天屏幕亮度的最大值
        screen_brightness_min = tmp_df.screen_brightness.min()  # 最近N天屏幕亮度的最小值
        screen_brightness_mean = tmp_df.screen_brightness.mean()  # 最近N天屏幕亮度的平均值

        sdcard_available_size_std = tmp_df.sdcard_available_size.std()  # 最近N天sd卡可用余量的标准差
        sdcard_available_size_max = tmp_df.sdcard_available_size.max()  # 最近N天sd卡可用余量的最大值
        sdcard_available_size_min = tmp_df.sdcard_available_size.min()  # 最近N天sd卡可用余量的最小值
        sdcard_available_size_mean = tmp_df.sdcard_available_size.mean()  # 最近N天sd卡可用余量的平均值
        feature_value_list.extend([report_cnt,
                                   advertising_id_cnt,
                                   and_id_cnt,
                                   boot_date_cnt,
                                   device_id_cnt,
                                   device_brand_cnt,
                                   gaid_cnt,
                                   ip_cnt,
                                   iso_country_cnt,
                                   background_recovery_times_sum,
                                   background_recovery_times_max,
                                   background_recovery_times_min,
                                   background_recovery_times_mean,
                                   battery_health_1_cnt,
                                   battery_health_2_cnt,
                                   battery_health_3_cnt,
                                   battery_health_1_rate,
                                   battery_health_2_rate,
                                   battery_health_3_rate,
                                   battery_power_std,
                                   battery_power_max,
                                   battery_power_min,
                                   battery_power_mean,
                                   battery_temperature_std,
                                   battery_temperature_max,
                                   battery_temperature_min,
                                   battery_temperature_mean,
                                   boot_time_std,
                                   boot_time_max,
                                   boot_time_min,
                                   boot_time_mean,
                                   charge_type_1_cnt,
                                   charge_type_2_cnt,
                                   charge_type_4_cnt,
                                   charge_type_1_rate,
                                   charge_type_2_rate,
                                   charge_type_4_rate,
                                   client_type_0_cnt,
                                   client_type_1_cnt,
                                   client_type_0_rate,
                                   client_type_1_rate,
                                   has_gravity_sensor_0_cnt,
                                   has_gravity_sensor_1_cnt,
                                   has_gravity_sensor_0_rate,
                                   has_gravity_sensor_1_rate,
                                   has_gyroscope_sensor_0_cnt,
                                   has_gyroscope_sensor_1_cnt,
                                   has_gyroscope_sensor_0_rate,
                                   has_gyroscope_sensor_1_rate,
                                   is_airplane_mode_0_cnt,
                                   is_airplane_mode_1_cnt,
                                   is_airplane_moder_0_rate,
                                   is_airplane_mode_1_rate,
                                   is_airplane_mode_0_cnt,
                                   is_airplane_mode_1_cnt,
                                   is_airplane_mode_0_rate,
                                   is_airplane_mode_1_rate,
                                   is_charging_1_cnt,
                                   is_charging_2_cnt,
                                   is_charging_3_cnt,
                                   is_charging_4_cnt,
                                   is_charging_5_cnt,
                                   is_charging_1_rate,
                                   is_charging_2_rate,
                                   is_charging_3_rate,
                                   is_charging_4_rate,
                                   is_charging_5_rate,
                                   is_mock_location_0_cnt,
                                   is_mock_location_1_cnt,
                                   is_mock_location_0_rate,
                                   is_mock_location_1_rate,
                                   is_root_0_cnt,
                                   is_root_1_cnt,
                                   is_root_0_rate,
                                   is_root_1_rate,
                                   is_tablet_0_cnt,
                                   is_tablet_1_cnt,
                                   is_tablet_0_rate,
                                   is_tablet_1_rate,
                                   is_usb_debug_0_cnt,
                                   is_usb_debug_1_cnt,
                                   is_usb_debug_0_rate,
                                   is_usb_debug_1_rate,
                                   is_usb_vpn_0_cnt,
                                   is_usb_vpn_1_cnt,
                                   is_usb_vpn_0_rate,
                                   is_usb_vpn_1_rate,
                                   is_keyboard_0_cnt,
                                   is_keyboard_1_cnt,
                                   is_keyboard_0_rate,
                                   is_keyboard_1_rate,
                                   ringer_mode_0_cnt,
                                   ringer_mode_1_cnt,
                                   ringer_mode_2_cnt,
                                   ringer_mode_0_rate,
                                   ringer_mode_1_rate,
                                   ringer_mode_1_rate,
                                   sim_count_0_cnt,
                                   sim_count_1_cnt,
                                   sim_count_2_cnt,
                                   sim_count_4_cnt,
                                   sim_count_0_rate,
                                   sim_count_1_rate,
                                   sim_count_1_rate,
                                   sim_count_1_rate,
                                   loan_page_stay_time_std,
                                   loan_page_stay_time_max,
                                   loan_page_stay_time_min,
                                   loan_page_stay_time_mean,
                                   ram_total_size_std,
                                   ram_total_size_max,
                                   ram_total_size_min,
                                   ram_total_size_mean,
                                   ram_usable_size_std,
                                   ram_usable_size_max,
                                   ram_usable_size_min,
                                   ram_usable_size_mean,
                                   read_privacy_agreement_time_std,
                                   read_privacy_agreement_time_max,
                                   read_privacy_agreement_time_min,
                                   read_privacy_agreement_time_mean,
                                   read_privacy_agreement_times_std,
                                   read_privacy_agreement_times_max,
                                   read_privacy_agreement_times_min,
                                   read_privacy_agreement_times_mean,
                                   screen_brightness_std,
                                   screen_brightness_max,
                                   screen_brightness_min,
                                   screen_brightness_mean,
                                   sdcard_available_size_std,
                                   sdcard_available_size_max,
                                   sdcard_available_size_min,
                                   sdcard_available_size_mean, ])
        feature_name_list.extend([f'report_cnt_{day}d',
                                  f'advertising_id_cnt_{day}d',
                                  f'and_id_cnt_{day}d',
                                  f'boot_date_cnt_{day}d',
                                  f'device_id_cnt_{day}d',
                                  f'device_brand_cnt_{day}d',
                                  f'gaid_cnt_{day}d',
                                  f'ip_cnt_{day}d',
                                  f'iso_country_cnt_{day}d',
                                  f'background_recovery_times_sum_{day}d',
                                  f'background_recovery_times_max_{day}d',
                                  f'background_recovery_times_min_{day}d',
                                  f'background_recovery_times_mean_{day}d',
                                  f'battery_health_1_cnt_{day}d',
                                  f'battery_health_2_cnt_{day}d',
                                  f'battery_health_3_cnt_{day}d',
                                  f'battery_health_1_rate_{day}d',
                                  f'battery_health_2_rate_{day}d',
                                  f'battery_health_3_rate_{day}d',
                                  f'battery_power_std_{day}d',
                                  f'battery_power_max_{day}d',
                                  f'battery_power_min_{day}d',
                                  f'battery_power_mean_{day}d',
                                  f'battery_temperature_std_{day}d',
                                  f'battery_temperature_max_{day}d',
                                  f'battery_temperature_min_{day}d',
                                  f'battery_temperature_mean_{day}d',
                                  f'boot_time_std_{day}d',
                                  f'boot_time_max_{day}d',
                                  f'boot_time_min_{day}d',
                                  f'boot_time_mean_{day}d',
                                  f'charge_type_1_cnt_{day}d',
                                  f'charge_type_2_cnt_{day}d',
                                  f'charge_type_4_cnt_{day}d',
                                  f'charge_type_1_rate_{day}d',
                                  f'charge_type_2_rate_{day}d',
                                  f'charge_type_4_rate_{day}d',
                                  f'client_type_0_cnt_{day}d',
                                  f'client_type_1_cnt_{day}d',
                                  f'client_type_0_rate_{day}d',
                                  f'client_type_1_rate_{day}d',
                                  f'has_gravity_sensor_0_cnt_{day}d',
                                  f'has_gravity_sensor_1_cnt_{day}d',
                                  f'has_gravity_sensor_0_rate_{day}d',
                                  f'has_gravity_sensor_1_rate_{day}d',
                                  f'has_gyroscope_sensor_0_cnt_{day}d',
                                  f'has_gyroscope_sensor_1_cnt_{day}d',
                                  f'has_gyroscope_sensor_0_rate_{day}d',
                                  f'has_gyroscope_sensor_1_rate_{day}d',
                                  f'is_airplane_mode_0_cnt_{day}d',
                                  f'is_airplane_mode_1_cnt_{day}d',
                                  f'is_airplane_moder_0_rate_{day}d',
                                  f'is_airplane_mode_1_rate_{day}d',
                                  f'is_airplane_mode_0_cnt_{day}d',
                                  f'is_airplane_mode_1_cnt_{day}d',
                                  f'is_airplane_mode_0_rate_{day}d',
                                  f'is_airplane_mode_1_rate_{day}d',
                                  f'is_charging_1_cnt_{day}d',
                                  f'is_charging_2_cnt_{day}d',
                                  f'is_charging_3_cnt_{day}d',
                                  f'is_charging_4_cnt_{day}d',
                                  f'is_charging_5_cnt_{day}d',
                                  f'is_charging_1_rate_{day}d',
                                  f'is_charging_2_rate_{day}d',
                                  f'is_charging_3_rate_{day}d',
                                  f'is_charging_4_rate_{day}d',
                                  f'is_charging_5_rate_{day}d',
                                  f'is_mock_location_0_cnt_{day}d',
                                  f'is_mock_location_1_cnt_{day}d',
                                  f'is_mock_location_0_rate_{day}d',
                                  f'is_mock_location_1_rate_{day}d',
                                  f'is_root_0_cnt_{day}d',
                                  f'is_root_1_cnt_{day}d',
                                  f'is_root_0_rate_{day}d',
                                  f'is_root_1_rate_{day}d',
                                  f'is_tablet_0_cnt_{day}d',
                                  f'is_tablet_1_cnt_{day}d',
                                  f'is_tablet_0_rate_{day}d',
                                  f'is_tablet_1_rate_{day}d',
                                  f'is_usb_debug_0_cnt_{day}d',
                                  f'is_usb_debug_1_cnt_{day}d',
                                  f'is_usb_debug_0_rate_{day}d',
                                  f'is_usb_debug_1_rate_{day}d',
                                  f'is_usb_vpn_0_cnt_{day}d',
                                  f'is_usb_vpn_1_cnt_{day}d',
                                  f'is_usb_vpn_0_rate_{day}d',
                                  f'is_usb_vpn_1_rate_{day}d',
                                  f'is_keyboard_0_cnt_{day}d',
                                  f'is_keyboard_1_cnt_{day}d',
                                  f'is_keyboard_0_rate_{day}d',
                                  f'is_keyboard_1_rate_{day}d',
                                  f'ringer_mode_0_cnt_{day}d',
                                  f'ringer_mode_1_cnt_{day}d',
                                  f'ringer_mode_2_cnt_{day}d',
                                  f'ringer_mode_0_rate_{day}d',
                                  f'ringer_mode_1_rate_{day}d',
                                  f'ringer_mode_1_rate_{day}d',
                                  f'sim_count_0_cnt_{day}d',
                                  f'sim_count_1_cnt_{day}d',
                                  f'sim_count_2_cnt_{day}d',
                                  f'sim_count_4_cnt_{day}d',
                                  f'sim_count_0_rate_{day}d',
                                  f'sim_count_1_rate_{day}d',
                                  f'sim_count_1_rate_{day}d',
                                  f'sim_count_1_rate_{day}d',
                                  f'loan_page_stay_time_std_{day}d',
                                  f'loan_page_stay_time_max_{day}d',
                                  f'loan_page_stay_time_min_{day}d',
                                  f'loan_page_stay_time_mean_{day}d',
                                  f'ram_total_size_std_{day}d',
                                  f'ram_total_size_max_{day}d',
                                  f'ram_total_size_min_{day}d',
                                  f'ram_total_size_mean_{day}d',
                                  f'ram_usable_size_std_{day}d',
                                  f'ram_usable_size_max_{day}d',
                                  f'ram_usable_size_min_{day}d',
                                  f'ram_usable_size_mean_{day}d',
                                  f'read_privacy_agreement_time_std_{day}d',
                                  f'read_privacy_agreement_time_max_{day}d',
                                  f'read_privacy_agreement_time_min_{day}d',
                                  f'read_privacy_agreement_time_mean_{day}d',
                                  f'read_privacy_agreement_times_std_{day}d',
                                  f'read_privacy_agreement_times_max_{day}d',
                                  f'read_privacy_agreement_times_min_{day}d',
                                  f'read_privacy_agreement_times_mean_{day}d',
                                  f'screen_brightness_std_{day}d',
                                  f'screen_brightness_max_{day}d',
                                  f'screen_brightness_min_{day}d',
                                  f'screen_brightness_mean_{day}d',
                                  f'sdcard_available_size_std_{day}d',
                                  f'sdcard_available_size_max_{day}d',
                                  f'sdcard_available_size_min_{day}d',
                                  f'sdcard_available_size_mean_{day}d', ])
    dev_fea_dict = dict(zip(feature_name_list, feature_value_list))
    for k,v in dev_fea_dict.items():
        if (v is None) or (isinstance(v, pd.Series)):
            dev_fea_dict[k] = -999
    feature_df = pd.DataFrame(dev_fea_dict, index=[0])
    feature_df.fillna(-999, inplace=True)
    return feature_df.to_dict(orient='records')[0]
